package flc.ast.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

// 导入Android主线程相关类
import android.os.Handler;
import android.os.Looper;

public class TCPServer {
    private ServerSocket serverSocket;
    private ExecutorService threadPool = Executors.newCachedThreadPool();
    private boolean isRunning = true;
    private MessageListener messageListener;
    // 存储所有客户端处理器
    private List<ClientHandler> clientHandlers = new ArrayList<>();
    // 将ScheduledExecutorService替换为Android主线程Handler
    private Handler mainHandler = new Handler(Looper.getMainLooper());
    private String receiveCharsetName = "UTF-8"; // 默认接收字符编码
    private String sendCharsetName = "UTF-8"; // 默认发送字符编码

    // 统计信息
    private int receivedCount = 0;        // 接收消息计数
    private int sentCount = 0;            // 发送消息计数
    private long receivedBytes = 0;       // 接收总字节数
    private long sentBytes = 0;           // 发送总字节数
    private long startTime = 0;           // 开始统计时间
    private int failedCount = 0;          // 失败次数

    // 消息回调接口
    public interface MessageListener {
        void onMessageReceived(String message);

        void onClientConnected(String ip);

        void onClientDisconnected(String ip);

        void onStatisticsUpdated(int receivedCount, int sentCount, double receiveSpeed, double sendSpeed, int failedCount);
    }

    // 设置消息监听器
    public void setMessageListener(MessageListener listener) {
        this.messageListener = listener;
    }

    // 设置字符编码（同时设置接收和发送）
    public void setCharsetName(String charsetName) {
        this.receiveCharsetName = charsetName;
        this.sendCharsetName = charsetName;
    }

    // 设置接收字符编码
    public void setReceiveCharsetName(String receiveCharsetName) {
        this.receiveCharsetName = receiveCharsetName;
    }

    // 设置发送字符编码
    public void setSendCharsetName(String sendCharsetName) {
        this.sendCharsetName = sendCharsetName;
    }

    public void start(int port) {
        try {
            // 创建未绑定的ServerSocket
            serverSocket = new ServerSocket(port);
//            // 允许地址重用
//            serverSocket.setReuseAddress(true);
//            // 绑定到指定端口
//            serverSocket.bind(new InetSocketAddress(port));
            new Thread(() -> {
                while (isRunning && !serverSocket.isClosed()) {
                    try {
                        Socket client = serverSocket.accept();
                        threadPool.execute(new ClientHandler(client));
                    } catch (IOException e) {
                        if (isRunning) e.printStackTrace();
                    }
                }
            }).start();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private class ClientHandler implements Runnable {
        private Socket clientSocket;
        private BufferedReader in;
        private PrintWriter out;

        // 向客户端发送消息
        public void sendMessage(String message) {
            if (this.out != null) {
                // 使用mainHandler在后台线程执行网络操作
//                mainHandler.post(() -> {
//                    this.out.println(message);
//                    sentCount++;
//                    sentBytes += message.getBytes().length;
//                    updateStatistics();
//                });
                new Thread(()->{
                    this.out.println(message);
                    sentCount++;
                    sentBytes += message.getBytes().length;
                    updateStatistics();
                }).start();
            }
        }

        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
            String ip = "";
            if (clientSocket != null && clientSocket.isConnected()) {
                String senderIp = clientSocket.getInetAddress().getHostAddress();
                int senderPort = clientSocket.getPort();
                ip = "[" + senderIp + ":" + senderPort + "]";
            }
            // 添加到客户端处理器列表
            synchronized (clientHandlers) {
                clientHandlers.add(this);
            }
            // 通知客户端连接
            notifyClientConnected(ip);
        }

        @Override
        public void run() {
            try {
                try {
                    in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), receiveCharsetName));
                    out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), sendCharsetName), true);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    failedCount++;
                    updateStatistics();
                    return;
                }

                String message;
                while ((message = in.readLine()) != null) {
                    if (clientSocket != null && clientSocket.isConnected()) {
                        String senderIp = clientSocket.getInetAddress().getHostAddress();
                        int senderPort = clientSocket.getPort();
                        message = "[" + senderIp + ":" + senderPort + "]" + message;
                    }
                    System.out.println("Received: " + message);
                    receivedCount++;
                    receivedBytes += message.getBytes().length;
//                    out.println("Server reply: " + message);
//                    sentCount++;
//                    sentBytes += ("Server reply: " + message).getBytes().length;
                    sentBytes += message.getBytes().length;
                    // 通知接收到消息
                    notifyMessageReceived(message);
                    updateStatistics();
                }
            } catch (IOException e) {
                e.printStackTrace();
                failedCount++;
                updateStatistics();
            } finally {
                try {
                    if (in != null) in.close();
                    if (out != null) out.close();
                    if (clientSocket != null) clientSocket.close();
                    String ip = "";
                    if (clientSocket != null && clientSocket.isConnected()) {
                        String senderIp = clientSocket.getInetAddress().getHostAddress();
                        int senderPort = clientSocket.getPort();
                        ip = "[" + senderIp + ":" + senderPort + "]";
                    }
                    // 从客户端处理器列表中移除
                    synchronized (clientHandlers) {
                        clientHandlers.remove(this);
                    }
                    // 通知客户端断开连接
                    notifyClientDisconnected(ip);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 通知接收到消息
    private void notifyMessageReceived(final String message) {
        if (messageListener != null) {
            mainHandler.post(new Runnable() {
            @Override
            public void run() {
                messageListener.onMessageReceived(message);
            }
        });
        }
    }

    // 通知客户端连接
    private void notifyClientConnected(String ip) {
        if (messageListener != null) {
            mainHandler.post(new Runnable() {
            @Override
            public void run() {
                messageListener.onClientConnected(ip);
                startTime = System.currentTimeMillis();
            }
        });
        }
    }

    // 更新统计信息
    private void updateStatistics() {
        if (messageListener == null) return;

        long currentTime = System.currentTimeMillis();
        double elapsedTime = (currentTime - startTime) / 1000.0; // 秒

        double receiveSpeed = elapsedTime > 0 ? receivedBytes / elapsedTime : 0; // B/s
        double sendSpeed = elapsedTime > 0 ? sentBytes / elapsedTime : 0; // B/s

        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                messageListener.onStatisticsUpdated(receivedCount, sentCount, receiveSpeed, sendSpeed, failedCount);
            }
        });
    }

    // 通知客户端断开连接
    private void notifyClientDisconnected(String ip) {
        if (messageListener != null) {
            mainHandler.post(new Runnable() {
            @Override
            public void run() {
                messageListener.onClientDisconnected(ip);
            }
        });
        }
    }

    // 向所有客户端发送消息
    public void sendMessageToAllClients(String message) {
        synchronized (clientHandlers) {
            for (ClientHandler clientHandler : clientHandlers) {
                clientHandler.sendMessage(message);
            }
        }
    }

    // 向特定IP的客户端发送消息
    public void sendMessageToClient(String ip, String message) {
        synchronized (clientHandlers) {
            for (ClientHandler clientHandler : clientHandlers) {
                if (clientHandler.clientSocket != null && clientHandler.clientSocket.isConnected()) {
                    String clientIp = clientHandler.clientSocket.getInetAddress().getHostAddress();
                    if (clientIp.equals(ip)) {
                        clientHandler.sendMessage(message);
                        break;
                    }
                }
            }
        }
    }

    public void stop() {
        isRunning = false;
        threadPool.shutdown();
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
